package com.sinodata.bsm.cicp.collector.sqlserver;

import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.List;

import org.apache.log4j.Logger;

import com.sinodata.bsm.cicp.collector.AbstractJDBCCollector;
import com.sinodata.bsm.cicp.exception.CollectorException;
import com.sinodata.bsm.common.constants.SeparatorConstants;
import com.sinodata.bsm.common.vo.ResPropertyValue;

public class Process extends AbstractJDBCCollector {
    private static final Logger logger = Logger.getLogger(Process.class);

    //    private static final int DEADLOCK_WAIT_TIME = 60;

    @Override
    public List<ResPropertyValue> collect(String ip) throws CollectorException {
        List<ResPropertyValue> values = new ArrayList<ResPropertyValue>();
        try {
            String[] propMetas = getPropMeta();
            //        String serverName = this.getParamMap().get("服务器名");
            String serverName = this.getParamMap().get("ServerName");

            String sql = "SELECT spid,ecid,loginame,DB_NAME(dbid) db_name,status," + " open_tran, cmd, program_name,waittime as 'waittime',waittype," + " waitresource,cpu, physical_io, memusage,login_time," + " last_batch, hostname,net_library, net_address,blocked" + " FROM master.dbo.sysprocesses ORDER by status";
            String[] rs = this.getStrings(serverName, sql, ip);

            ResPropertyValue propertyValueX = new ResPropertyValue();
            ResPropertyValue.PropValue[] propValues = new ResPropertyValue.PropValue[propMetas.length];
            for (int i = 0; i < propMetas.length; i++) {
                propValues[i] = ResPropertyValue.createPropValue(rs[i], propMetas[i]);
            }
            propertyValueX.setValues(propValues);
            values.add(propertyValueX);
        } catch (Exception e) {
            logger.error("failed to collect sqlserver process", e);

            throw new CollectorException(e);
        }
        return values;
    }

    private String[] getStrings(String serverName, String sql, String ip) throws CollectorException {
        String[] propValArr = new String[5];

        try {
            ResultSet rst = this.getCachedResultSet("sqlserver", ip, serverName, sql);
            int processCount = 0;
            int sysProcessCount = 0;
            int userProcessCount = 0;
            StringBuffer processDetail = new StringBuffer();
            if (rst != null) {
                // 进程ID|环境ID|用户|数据库|状态|打开事务|命令|应用程序|等待时间|等待类型|等待资源|CPU|物理IO|内存使用|登录时间|上次批处理|主机|网络库|网络地址|阻塞者
                //                processDetail.append("Process ID").append(SeparatorConstants.COL_SEPARATOR);//进程ID
                //                processDetail.append("Environment ID").append(SeparatorConstants.COL_SEPARATOR);//环境ID
                //                processDetail.append("User").append(SeparatorConstants.COL_SEPARATOR);//用户
                //                processDetail.append("Database").append(SeparatorConstants.COL_SEPARATOR);//数据库
                //                processDetail.append("Status").append(SeparatorConstants.COL_SEPARATOR);//状态
                //                processDetail.append("Open Transaction").append(SeparatorConstants.COL_SEPARATOR);//打开事务
                //                processDetail.append("Command").append(SeparatorConstants.COL_SEPARATOR);//命令
                //                processDetail.append("Application").append(SeparatorConstants.COL_SEPARATOR);//应用程序
                //                processDetail.append("Wait Time").append(SeparatorConstants.COL_SEPARATOR);//等待时间
                //                processDetail.append("Wait Type").append(SeparatorConstants.COL_SEPARATOR);//等待类型
                //                processDetail.append("Wait Resource").append(SeparatorConstants.COL_SEPARATOR);//等待资源
                //                processDetail.append("CPU").append(SeparatorConstants.COL_SEPARATOR);//CPU
                //                processDetail.append("Physics IO").append(SeparatorConstants.COL_SEPARATOR);//物理IO
                //                processDetail.append("Memory Use").append(SeparatorConstants.COL_SEPARATOR);//内存使用
                //                processDetail.append("Login Time").append(SeparatorConstants.COL_SEPARATOR);//登录时间
                //                processDetail.append("Last Batching").append(SeparatorConstants.COL_SEPARATOR);//上次批处理
                //                processDetail.append("Host").append(SeparatorConstants.COL_SEPARATOR);//主机
                //                processDetail.append("Network Library").append(SeparatorConstants.COL_SEPARATOR);//网络库
                //                processDetail.append("Network Address").append(SeparatorConstants.COL_SEPARATOR);//网络地址
                //                processDetail.append("Obstructor").append(SeparatorConstants.COL_SEPARATOR);//阻塞者
                //                processDetail.append(SeparatorConstants.LIN_SEPARATOR);
                while (rst.next()) {
                    processCount++;
                    int spid = rst.getInt(1);
                    if (spid > 50) {// SQL Server2000&2005
                        userProcessCount++;
                    } else
                        sysProcessCount++;

                    String line = getTabLineStr(rst, 20);
                    processDetail.append(line).append(SeparatorConstants.LIN_SEPARATOR);
                }
                String processDetailstr = processDetail.toString();

                propValArr[0] = processCount + "";
                propValArr[1] = "" + sysProcessCount;
                propValArr[2] = "" + userProcessCount;
                propValArr[3] = "" + 0;
                propValArr[4] = processDetailstr;

                return propValArr;
            } else {
                return null;
            }
        } catch (Exception ex) {
            logger.error("while connect database : ", ex);
            throw new CollectorException(ex);
        }
    }

    private String getTabLineStr(ResultSet rst, int colNum) throws CollectorException {
        StringBuffer tabLineStr = new StringBuffer();
        try {
            for (int i = 1; i <= colNum; i++) {
                String val = rst.getString(i);
                if (val == null || val.trim().length() == 0) {
                    val = " ";
                } else
                    val = val.trim();
                tabLineStr.append(val).append(SeparatorConstants.COL_SEPARATOR);
            }
        } catch (Exception e) {
            logger.error("failed to get TabLineStr ", e);
            throw new CollectorException(e);
        }
        return tabLineStr.toString();
    }

    @Override
    public String[] getParamMeta() {
        return new String[] { "ServerName" };
    }

    @Override
    public String[] getPropMeta() {
        return new String[] { "TotalProcesses", "SystemProcesses", "UserProcesses", "DeadlockProcesses", "ProcessDetailedInfo" };
    }

}
